package admin

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"outsourced-projects/pkg/communal"
	"outsourced-projects/pkg/utils"
	"outsourced-projects/service"
	"strings"
	"time"
)

type Staff struct {
	service.Base
}

func (staff Staff) StaffExt(c *gin.Context) {
	var err error
	//数据获取
	jsondata := make(map[string]interface{})
	err = c.BindJSON(&jsondata)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}
	if cast.ToString(jsondata["userid"]) == "" {
		service.ReturnJson(c, 400, errors.New("userid不能为空").Error(), gin.H{})
		return
	}

	//初始化数据库
	db := communal.Sql()
	defer db.Close()

	extdata, err := db.QueryString(fmt.Sprintf("select * from `staff_ext` where userid = '%s'", cast.ToString(jsondata["userid"])))
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	data := make(map[string]interface{})
	data["mobile"] = cast.ToString(jsondata["mobile"])
	data["email"] = cast.ToString(jsondata["email"])
	data["employment"] = cast.ToString(jsondata["employment"])
	if len(extdata) > 0 { //更新
		_, err = db.Table("staff_ext").Where("userid = ?", cast.ToString(jsondata["userid"])).Cols("mobile", "email", "employment").Update(data)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
	} else { //新增
		data["userid"] = cast.ToString(jsondata["userid"])
		_, err = db.Table("staff_ext").Insert(data)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
	}
	service.ReturnJson(c, 200, "操作成功", gin.H{})
}

func (staff Staff) List(c *gin.Context) {
	var err error
	//数据获取
	jsondata := make(map[string]interface{})
	err = c.BindJSON(&jsondata)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	//初始化数据库
	db := communal.Sql()
	defer db.Close()

	limitstr := fmt.Sprintf(" limit %d,%d", (cast.ToInt(jsondata["page_index"])-1)*cast.ToInt(jsondata["page_size"]), cast.ToInt(jsondata["page_size"]))
	orderstr := " order by a.`userid` desc"

	//if cast.ToString(jsondata["department"]) == "" {
	//	service.ReturnJson(c, 400, errors.New("部门id不能为空").Error(), gin.H{})
	//	return
	//}

	wheresql := strings.Builder{}

	if cast.ToString(jsondata["department"]) != "0" {
		relationship, err := db.QueryString(fmt.Sprintf("select relationship from department where id = %s limit 1", cast.ToString(jsondata["department"])))
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
		wheresql.WriteString(fmt.Sprintf(" and b.`relationship` like '%s'", relationship[0]["relationship"]+"%"))
	} else {
		wheresql.WriteString(fmt.Sprintf(" and b.`relationship` like '%s'", "-1-79-"+"%"))
	}

	if cast.ToString(jsondata["staff"]) != "" {
		wheresql.WriteString(fmt.Sprintf(" and a.`name` like '%s'", "%"+cast.ToString(jsondata["staff"])+"%"))
	}

	listsql := fmt.Sprintf("select a.`userid`,a.`name`,a.`position` from `staff` as a left join department b on a.main_department = b.id where 1=1 %s %s %s", wheresql.String(), orderstr, limitstr)
	listdata, err := db.QueryString(listsql)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	countsql := fmt.Sprintf("select count(*) as total from `staff` as a left join department b on a.main_department = b.id where 1=1 %s", wheresql.String())
	countdata, err := db.QueryString(countsql)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	for k, v := range listdata {
		ext, err := db.QueryString(fmt.Sprintf("select * from `staff_ext` where `userid` = '%s' limit 1", v["userid"]))
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
		if len(ext) > 0 {
			listdata[k]["mobile"] = ext[0]["mobile"]
			listdata[k]["email"] = ext[0]["email"]
			listdata[k]["employment"] = ext[0]["employment"]
		} else {
			listdata[k]["mobile"] = ""
			listdata[k]["email"] = ""
			listdata[k]["employment"] = ""
		}
	}

	service.ReturnJson(c, 200, "操作成功", gin.H{
		"list":  listdata,
		"total": cast.ToInt(countdata[0]["total"]),
	})
}

func (staff Staff) SyncStaff(c *gin.Context) {
	type StaffStruct struct {
		Userlist []struct {
			Userid     string `json:"userid"`
			Name       string `json:"name"`
			Department []int  `json:"department"`
			Position   string `json:"position"`
			Status     int    `json:"status"`
			Extattr    struct {
				Attrs []struct {
					Name  string `json:"name"`
					Value string `json:"value"`
					Type  int    `json:"type"`
					Text  struct {
						Value string `json:"value"`
					} `json:"text"`
				} `json:"attrs,omitempty"`
			} `json:"extattr"`
			Telephone       string `json:"telephone"`
			Order           []int  `json:"order"`
			ExternalProfile struct {
				ExternalCorpName string `json:"external_corp_name,omitempty"`
				WechatChannels   struct {
					Nickname string `json:"nickname"`
					Status   int    `json:"status"`
				} `json:"wechat_channels,omitempty"`
			} `json:"external_profile,omitempty"`
			MainDepartment   int      `json:"main_department"`
			Alias            string   `json:"alias"`
			IsLeaderInDept   []int    `json:"is_leader_in_dept"`
			DirectLeader     []string `json:"direct_leader,omitempty"`
			ExternalPosition string   `json:"external_position,omitempty"`
		} `json:"userlist"`
	}
	var err error
	//数据获取
	jsondata := make(map[string]interface{})
	err = c.BindJSON(&jsondata)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	//userid, ok := c.Get("userid")
	//if !ok {
	//	service.ReturnJson(c, 500, errors.New("userid获取失败").Error(), gin.H{})
	//	return
	//}
	//if cast.ToInt(userid) != 1 {
	//	service.ReturnJson(c, 500, errors.New("当前账号不允许操作").Error(), gin.H{})
	//	return
	//}

	//初始化数据库
	db := communal.Sql()
	defer db.Close()

	dbsession := db.NewSession()
	defer dbsession.Close()
	dbsession.Begin()

	//清除表
	_, err = dbsession.Exec(fmt.Sprint("TRUNCATE TABLE staff;"))
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	jobid, err := utils.ExportUser()
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	time.Sleep(3 * time.Second)

	exportRes, err := utils.ExportGetResult(jobid)
	for _, v := range exportRes {
		//解析下载内容
		data, err := utils.AesDecodeContent(v.Url)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
		//数据写入数据库
		syncdata := make(map[string]interface{})
		syncdata["type"] = "staff"
		syncdata["content"] = string(data)
		syncdata["md5"] = v.Md5
		syncdata["sizebig"] = v.Size
		syncdata["addtime"] = time.Now().Unix()
		_, err = db.Table("sync_log").Insert(syncdata)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}

		//写入数据
		staffData := StaffStruct{}
		err = json.Unmarshal(data, &staffData)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
		for _, v := range staffData.Userlist {
			staffinsert := make(map[string]interface{})
			staffinsert["userid"] = v.Userid
			staffinsert["name"] = v.Name
			department, _ := json.Marshal(v.Department)
			staffinsert["department"] = string(department)
			order, _ := json.Marshal(v.Order)
			staffinsert["order"] = string(order)
			staffinsert["position"] = v.Position
			isLeaderInDept, _ := json.Marshal(v.IsLeaderInDept)
			staffinsert["is_leader_in_dept"] = string(isLeaderInDept)
			directLeader, _ := json.Marshal(v.DirectLeader)
			staffinsert["direct_leader"] = string(directLeader)
			staffinsert["telephone"] = v.Telephone
			staffinsert["alias"] = v.Alias
			staffinsert["status"] = v.Status
			staffinsert["main_department"] = v.MainDepartment
			extattr, _ := json.Marshal(v.Extattr)
			staffinsert["extattr"] = string(extattr)
			staffinsert["external_position"] = v.ExternalPosition
			externalProfile, _ := json.Marshal(v.ExternalProfile)
			staffinsert["external_profile"] = string(externalProfile)
			staffinsert["sync_time"] = time.Now().Unix()
			_, err = dbsession.Table("staff").Insert(staffinsert)
			if err != nil {
				dbsession.Rollback()
				service.ReturnJson(c, 500, err.Error(), gin.H{})
				return
			}
		}
	}
	dbsession.Commit()
	service.ReturnJson(c, 200, "操作成功", gin.H{})
}

type DepartmentTreeStruct struct {
	Id          int                     `json:"id"`
	ParentId    int                     `json:"parentid"`
	Name        string                  `json:"name"`
	StaffNumber int                     `json:"staffnumber"`
	Subset      []*DepartmentTreeStruct `json:"subset"`
}

func (staff Staff) DepartmentTree(tree *DepartmentTreeStruct, v map[string]string) {
	if cast.ToInt(v["parentid"]) == 1 {
		tree.Subset = append(tree.Subset, &DepartmentTreeStruct{
			cast.ToInt(v["id"]),
			cast.ToInt(v["parentid"]),
			cast.ToString(v["name"]),
			cast.ToInt(v["staff_number"]),
			nil,
		})
	} else {
		if len(tree.Subset) > 0 {
			for key, value := range tree.Subset {
				if value.Id == cast.ToInt(v["parentid"]) {
					tree.Subset[key].Subset = append(tree.Subset[key].Subset, &DepartmentTreeStruct{
						Id:          cast.ToInt(v["id"]),
						ParentId:    cast.ToInt(v["parentid"]),
						Name:        cast.ToString(v["name"]),
						StaffNumber: cast.ToInt(v["staff_number"]),
						Subset:      nil,
					})
				} else {
					staff.DepartmentTree(tree.Subset[key], v)
				}
			}
		}
	}
}

func (staff Staff) Department(c *gin.Context) {
	var err error
	//数据获取
	jsondata := make(map[string]interface{})
	err = c.BindJSON(&jsondata)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	db := communal.Sql()
	defer db.Close()

	DepartmentReturn := &DepartmentTreeStruct{}

	sqlstr := fmt.Sprintf("select * from `department` where `relationship` like '%s' order by parentid asc,`order` desc", "%-1-79-%")
	listdata, err := db.QueryString(sqlstr)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}
	for _, val := range listdata {
		staff.DepartmentTree(DepartmentReturn, val)
	}

	service.ReturnJson(c, 200, "操作成功", gin.H{
		"list":  DepartmentReturn.Subset,
		"total": len(listdata),
	})
}

func (staff Staff) SyncDepartment(c *gin.Context) {
	type DepartmentStruct struct {
		Department []struct {
			Id       int    `json:"id"`
			Name     string `json:"name"`
			Parentid int    `json:"parentid"`
			Order    int    `json:"order"`
		} `json:"department"`
	}
	var err error
	//数据获取
	jsondata := make(map[string]interface{})
	err = c.BindJSON(&jsondata)
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	userid, ok := c.Get("userid")
	if !ok {
		service.ReturnJson(c, 500, errors.New("userid获取失败").Error(), gin.H{})
		return
	}
	if cast.ToInt(userid) != 1 {
		service.ReturnJson(c, 500, errors.New("当前账号不允许操作").Error(), gin.H{})
		return
	}

	//初始化数据库
	db := communal.Sql()
	defer db.Close()

	dbsession := db.NewSession()
	defer dbsession.Close()
	dbsession.Begin()

	//清除表
	_, err = dbsession.Exec(fmt.Sprint("TRUNCATE TABLE department;"))
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}

	jobid, err := utils.ExportDepartment()
	if err != nil {
		service.ReturnJson(c, 500, err.Error(), gin.H{})
		return
	}
	time.Sleep(3 * time.Second)

	exportRes, err := utils.ExportGetResult(jobid)

	for _, v := range exportRes {
		fmt.Println(v.Url)
		//解析下载内容
		data, err := utils.AesDecodeContent(v.Url)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
		//记录请求数据
		syncdata := make(map[string]interface{})
		syncdata["type"] = "department"
		syncdata["content"] = string(data)
		syncdata["md5"] = v.Md5
		syncdata["sizebig"] = v.Size
		syncdata["addtime"] = time.Now().Unix()
		_, err = db.Table("sync_log").Insert(syncdata)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}

		//写入数据
		departmentData := DepartmentStruct{}
		err = json.Unmarshal(data, &departmentData)
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}

		for i := 0; i < len(departmentData.Department); i++ {
			departmentinsert := make(map[string]interface{})
			departmentinsert["id"] = departmentData.Department[i].Id
			departmentinsert["name"] = departmentData.Department[i].Name
			departmentinsert["parentid"] = departmentData.Department[i].Parentid
			departmentinsert["order"] = departmentData.Department[i].Order
			departmentinsert["sync_time"] = time.Now().Unix()
			//部门人数统计
			count, err := db.Table("staff").Where(fmt.Sprintf("`main_department` = %d", departmentData.Department[i].Id)).Count()
			if err != nil {
				service.ReturnJson(c, 500, err.Error(), gin.H{})
				return
			}
			departmentinsert["staff_number"] = count

			_, err = dbsession.Table("department").Insert(departmentinsert)
			if err != nil {
				dbsession.Rollback()
				service.ReturnJson(c, 500, err.Error(), gin.H{})
				return
			}
		}

		department, err := dbsession.QueryString(fmt.Sprintf("select * from department order by parentid asc"))
		if err != nil {
			service.ReturnJson(c, 500, err.Error(), gin.H{})
			return
		}
		for i := 0; i < len(department); i++ {
			fmt.Println("============== 同步")
			fmt.Println(department[i]["parentid"])
			relationship := ""
			if cast.ToInt(department[i]["parentid"]) > 0 {
				parentidRelationship, err := dbsession.QueryString(fmt.Sprintf("select relationship from department where id = %s limit 1", department[i]["parentid"]))
				if err != nil {
					service.ReturnJson(c, 500, err.Error(), gin.H{})
					return
				}
				parentidRelationshipStr := parentidRelationship[0]["relationship"]
				//relationship += fmt.Sprintf("%s", parentidRelationship)
				relationship = parentidRelationshipStr[:len(parentidRelationshipStr)-1]
			}
			relationship += fmt.Sprintf("-%s-", department[i]["id"])
			_, _ = dbsession.Exec(fmt.Sprintf("UPDATE `department` SET `relationship` = '%s' WHERE `id` = %s;", relationship, department[i]["id"]))
		}

		//for _, v := range departmentData.Department {
		//
		//}
	}

	dbsession.Commit()
	service.ReturnJson(c, 200, "操作成功", gin.H{})
}
